#include "GY_NTreeView.h"

const int GY_NTreeView::m_dataRole = Qt::UserRole + 1;
const int GY_NTreeView::m_IdRole = Qt::UserRole + 2;

GY_NTreeView::GY_NTreeView(QWidget *parent):QTreeView(parent),GY_NStyle(this)
{
    this->setAttribute(Qt::WA_StyledBackground);
    //初始化模型
    m_model = new QStandardItemModel();
    this->setModel(m_model);
    //隔行样式
    this->setAlternatingRowColors(true);
}

/**
 * @brief setHorizontalHeaderLabels 设置表头
 * @param list
 */
void GY_NTreeView::setHorizontalHeaderLabels(const QStringList &list)
{
    for(int i = 0; i < list.size(); i++){
        QString str = list.at(i);
        addColumnName(str);
    }
}

/**
 * @brief addRowData 插入一行数据，需要传入父 index, 如果不传则为顶级节点
 * @param list
 * @param id
 * @param parent
 * @return
 */
QModelIndex GY_NTreeView::addRowData(const QList<QVariant> &list, const QVariant &id, const QModelIndex &parent)
{
    if(list.length() != m_model->columnCount()){
        qDebug() << "void ControlTreeView::addRowData(const QList<QVariant> &list) 注意 list.length() =" << list.length() << "m_model->columnCount() = " << m_model->columnCount();
    }
    QList<QStandardItem *> itemArray;
    QStandardItem *item = nullptr;
    for(int i= 0; i < list.length(); i++)
    {
        QVariant data = list.at(i);
        item = nullptr;
        item = new QStandardItem();

        if(i == 0) {
            item->setData(QVariant::fromValue<QList<QVariant>>(list), m_dataRole);
            item->setData(id, m_IdRole);
        }
        if(i == 0 && m_hasCheckBox){
            item->setCheckable(true);
            item->setCheckState(Qt::Unchecked);
        }
        if(!m_RegisterInfo.contains(i))
        {
            item->setText(data.toString());
        }
        item->setTextAlignment(Qt::AlignCenter);
        itemArray << item;
    }
    int row = 0;
    if(!parent.isValid()){
        row = m_model->rowCount();
        m_model->appendRow(itemArray);
    }else{
        QStandardItem *pItem = m_model->itemFromIndex(parent);
        row =  pItem->rowCount();
        pItem->appendRow(itemArray);
    }
    QMap<qint32,QString>::iterator iter;

    for(iter = m_RegisterInfo.begin(); iter != m_RegisterInfo.end(); iter++){
        int column = iter.key();
        QVariant data = list.at(column);
        QString className = iter.value();
        QWidget* pWidget=WidgetReflect::newInstance(className,this);
        if(nullptr==pWidget)
        {
            pWidget=m_RegisterHash.value(className)(this);
            if(nullptr==pWidget)
            {
                qDebug()<<"实例化自定义控件："<<className<<"失败";
                item->setText(data.toString());
                m_model->setItem(row,column,item);
                continue;
            }
        }
        GY_NAbstractItemWidget *itemWidget =  ((GY_NAbstractItemWidget*)pWidget);
        itemWidget->setData(data);
        itemWidget->setPosition(id,column);
        QModelIndex targetIdx = m_model->index(row, column, parent);
        setIndexWidget(targetIdx,pWidget);
        connect(itemWidget, &GY_NAbstractItemWidget::controlDataUpdate, this, [=](const QVariant &rowID,const qint32 &columenIndex,const QVariant &data){
            emit clickedCustomWidged(rowID,columenIndex,data);
        });
    }
    return m_model->index(row, 0, parent);
}
/**
 * @brief getModelIndexById 获取某id所在行的 QModelIndex
 * @param id
 * @param parent
 * @return
 */
QModelIndex GY_NTreeView::getModelIndexById(const QVariant &id, const QModelIndex &parent)
{
    if(parent.isValid()){
        QStandardItem *pItem = m_model->itemFromIndex(parent);
        if(getItemId(pItem) == id)
            return parent;

        for(int i = 0; i < pItem->rowCount(); ++i){
            QStandardItem *item = pItem->child(i);
            QModelIndex index = getModelIndexById(id, item->index());

            if(index.isValid()){
                return index;
            }
        }
    }else{

        for(int i = 0; i < m_model->rowCount(); ++i){
            QStandardItem *item = m_model->item(i);
            QModelIndex index = getModelIndexById(id, item->index());

            if(index.isValid()){
                return index;
            }
        }
    }

    return QModelIndex();
}
/**
 * @brief getItemId 获取Itemid
 * @param item
 * @return
 */
QVariant GY_NTreeView::getItemId(const QStandardItem *item)
{
    return item->data(m_IdRole);
}
/**
 * @brief removeAllData 删除所有数据
 */
void GY_NTreeView::removeAllData()
{
    m_model->removeRows(0,m_model->rowCount());
}
/**
 * @brief setHasCheckBox 设置是否将第一列设置成复选框,
 * @param value
 */
void GY_NTreeView::setHasCheckBox(bool value)
{
    m_hasCheckBox = value;
}
/**
 * @brief getCheckStateAtRow 获取某行的选中状态
 * @param row
 * @param parent
 * @return
 */
bool GY_NTreeView::getCheckStateAtRow(int row, const QModelIndex &parent)
{
    if(!m_hasCheckBox) return Qt::Unchecked;
    QStandardItem *item = nullptr;
    if(parent.isValid()){
        QStandardItem *pItem = m_model->itemFromIndex(parent);
        item = pItem->child(row);
    }else{
        item = m_model->item(row);
    }

    return item->checkState() == Qt::Checked;
}

bool GY_NTreeView::getCheckStateByItem(QStandardItem *item)
{
    if(item == nullptr) return false;
    return item->checkState() ==  Qt::Checked;
}
/**
 * @brief setRowCheckState 设置某行的选中状状态
 * @param row
 * @param isChecked
 * @param parent
 */
void GY_NTreeView::setRowCheckState(int row, bool isChecked, const QModelIndex &parent)
{
    if(!m_hasCheckBox) return;
    QStandardItem *item = nullptr;
    if(parent.isValid()){
        QStandardItem *pItem = m_model->itemFromIndex(parent);
        item = pItem->child(row);
    }else{
        item = m_model->item(row);

    }
    Qt::CheckState state = isChecked ? Qt::Checked : Qt::Unchecked;
    item->setCheckState(state);
}
/**
 * @brief deleteCheckedRow 删除选中行
 * @param pItem
 */
void GY_NTreeView::deleteCheckedRow(QStandardItem *pItem)
{
    if(!m_hasCheckBox) return;

    if(pItem ==  nullptr){
        int row = 0;
        while(row < m_model->rowCount()){
            if(getCheckStateAtRow(row)){
                deleteRowByIndex(row);
            }else{
                QStandardItem *item = m_model->item(row);
                deleteCheckedRow(item);
                row++;
            }
        }
    }else{
        int row = 0;
        QModelIndex pIndex = pItem->index();
        while(row < pItem->rowCount()){
            if(getCheckStateAtRow(row, pIndex)){
                deleteRowByIndex(row, pIndex);
            }else{
                QStandardItem *item = pItem->child(row);
                deleteCheckedRow(item);
                row++;
            }
        }
    }
}
/**
 * @brief getCheckedDatas 获取选中的数据
 * @param list
 * @param pItem
 */
void GY_NTreeView::getCheckedDatas(QList<QList<QVariant> > &list, QStandardItem *pItem)
{
    if(pItem == nullptr){
        for(int i = 0; i < m_model->rowCount(); ++i){
            QStandardItem *item = m_model->item(i);
            getCheckedDatas(list, item);
        }
    }else{
        if(getCheckStateByItem(pItem)){
            list.push_back(pItem->data(m_dataRole).value<QList<QVariant>>());
        }

        for(int i = 0; i < pItem->rowCount(); ++i){
            QStandardItem *item = pItem->child(i);
            getCheckedDatas(list, item);
        }
    }
}
/**
 * @brief getCheckedDataIds 获取当前选选择行ID
 * @param idList
 * @param pItem
 */
void GY_NTreeView::getCheckedDataIds(QVector<QVariant> &idList, QStandardItem *pItem)
{
    if(pItem == nullptr){
        for(int i = 0; i < m_model->rowCount(); ++i){
            QStandardItem *item = m_model->item(i);
            getCheckedDataIds(idList, item);
        }
    }else{
        if(getCheckStateByItem(pItem)){
            idList<<getItemId(pItem);
        }

        for(int i = 0; i < pItem->rowCount(); ++i){
            QStandardItem *item = pItem->child(i);
            getCheckedDataIds(idList, item);
        }
    }
}
/**
 * @brief getDataById 通过id获取数据
 * @param id
 * @return
 */
QList<QVariant> GY_NTreeView::getDataById(const QVariant &id)
{
    QModelIndex index = getModelIndexById(id);
    if(index.isValid()){
        QStandardItem *item = m_model->itemFromIndex(index);
        return item->data(m_dataRole).value<QList<QVariant>>();
    }
    return QList<QVariant>();
}
/**
 * @brief getCurrentSelectId 获取当前选中行
 * @return
 */
QVariant GY_NTreeView::getCurrentSelectId()
{
    QModelIndex mindex = currentIndex();
    if(-1==mindex.row())
    {
        return -1;
    }
    mindex=mindex.sibling(mindex.row(),0);
    QStandardItem *item=m_model->itemFromIndex(mindex);
    return getItemId(item);
}
/**
 * @brief updateDataById 通过id更新数据
 * @param id
 * @param list
 * @param isChecked
 */
void GY_NTreeView::updateDataById(const QVariant &id, const QList<QVariant> &list, bool isChecked)
{
    QModelIndex index = getModelIndexById(id);
    if(!index.isValid()) return;

    QModelIndex pIndex = index.parent();
    QStandardItem * item = nullptr;
    int row = index.row();
    for(int i= 0; i < list.length(); i++)
    {
        QVariant data = list.at(i);
        item = nullptr;
        if(pIndex.isValid()){
            QStandardItem *pItem = m_model->itemFromIndex(pIndex);
            item = pItem->child(row, i);
        }else{
            item = m_model->item(row, i);

        }
        if(i == 0) {
            item->setData(QVariant::fromValue<QList<QVariant>>(list), m_dataRole);
            item->setData(id, m_IdRole);
        }
        if(i == 0 && m_hasCheckBox){
            item->setCheckable(true);
            item->setCheckState(isChecked ? Qt::Checked : Qt::Unchecked);
        }
        if(!m_RegisterInfo.contains(i))
        {
            item->setText(data.toString());
        }
        item->setTextAlignment(Qt::AlignCenter);
    }
    QMap<qint32,QString>::iterator iter;
    for(iter = m_RegisterInfo.begin(); iter != m_RegisterInfo.end(); iter++){
        int column = iter.key();
        QVariant data = list.at(column);
        QWidget* pWidget = indexWidget(m_model->index(index.row(), column , index.parent()));
        if(nullptr==pWidget)
        {
            qDebug()<<"更新自定义控件："<<m_RegisterInfo.value(column)<<"失败";
            item->setText(data.toString());
            continue;
        }
        ((GY_NAbstractItemWidget*)pWidget)->setData(data);
    }
}
/**
 * @brief deleteRowByIndex 删除目标行
 * @param row
 * @param parent
 */
void GY_NTreeView::deleteRowByIndex(int row, const QModelIndex &parent)
{
    if(parent.isValid()){
        QStandardItem *pItem = m_model->itemFromIndex(parent);
        pItem->removeRow(row);
    }else{
        m_model->removeRow(row);
    }
}
/**
 * @brief deleteRowById 根据Id删除行
 * @param id
 */
void GY_NTreeView::deleteRowById(const QVariant &id)
{
    QModelIndex index=getModelIndexById(id);
    deleteRowByIndex(index.row(),index.parent());
}
/**
 * @brief setColumnCount 设置列数
 * @param value 值
 */
void GY_NTreeView::setColumnCount(int value)
{
    m_model->setColumnCount(value);
}
/**
 * @brief addColumnName 添加列
 * @param name 列名称
 */
void GY_NTreeView::addColumnName(const QString &name)
{
    QStandardItem *item = new QStandardItem;
    item->setText(name);
    item->setTextAlignment(Qt::AlignCenter);
    int i = m_model->columnCount();
    m_model->setHorizontalHeaderItem(i, item);
}

QStandardItemModel *GY_NTreeView::getModel()
{
    return m_model;
}
